package thread;

import org.checkerframework.checker.units.qual.A;

import javax.sound.midi.Soundbank;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author
 * @date 2021年09月08日 12:59
 * @description
 */
public class CompletableFutureDemo {


    public static void main(String[] args) {
        // 开启一个异步方法
        CompletableFuture<List> future = CompletableFuture.supplyAsync(() -> {
            List<String> list = new ArrayList<>();
            list.add("语文");
            list.add("数学");
            // 获取得到今天的所有课程
            return list;
        });
        // 使用handle()方法接收list数据和error异常
        CompletableFuture<Integer> future2 = future.handle((list, error) -> {
            // 如果报错，就打印出异常
            error.printStackTrace();
            // 如果不报错，返回一个包含Integer的全新的CompletableFuture
            return list.size();
            // 注意这里的两个CompletableFuture包含的返回类型不同
        });


        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            return null;
        });

        CompletableFuture<String> exceptionly = future1.thenApply(result -> {
            int i = result;
            return i;
        }).thenApply(time -> {
            return "时间" + time;
        }).exceptionally(error -> {
            error.printStackTrace();
            return error.getMessage();
        });

        exceptionly.thenAccept((System.out::println));

//        Stream.of(new ArrayList<>(), new ArrayList<>()).flatMap(Collection::stream).collect(Collectors.toList());


        long begin = System.currentTimeMillis();
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        List<CompletableFuture<Integer>> collect = IntStream.range(1, 10).mapToObj(i -> {
            CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> {
                if (i == 5) {
                    throw new NullPointerException();
                }
                try {
                    TimeUnit.SECONDS.sleep(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(i);
                return i;
            }, executorService).exceptionally(error -> {
                try {
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return 100;
            });
            return future3;
        }).collect(Collectors.toList());

        CompletableFuture.allOf(collect.toArray(new CompletableFuture[]{})).join();
        System.out.println("最终耗时" + (System.currentTimeMillis() - begin) + "毫秒");
        executorService.shutdown();

    }


}
